#ifndef REPOUTIL_H
#define REPOUTIL_H

#include <QJsonDocument>
#include <QJsonObject>
#include <QString>
#include <QStringList>
#include <QVariantList>

struct Validate {
    bool a;
    QString b;
};

struct Result {
    bool a;
    QString b;
};

class RepoUtil
{
public:
    RepoUtil();

    static bool isVerify(QString &dir);

    static QString _paths(const QStringList &paths);
    static QString _paths(const QString &path, const QString &path1);
    static QString _paths(const QString &path, const QString &path1, const QString &path2);
    static QString _paths(const QString &path, const QString &path1, const QString &path2, const QString &path3);
    static QString _paths(const QString &path, const QString &path1, const QString &path2, const QString &path3, const QString &path4);

    static bool _dir_exists(const QString &dir);
    static bool _dir_exists(const QStringList &dirs);
    static bool _dir_exists(const QString &dir, const QString &dir1);
    static bool _dir_exists(const QString &dir, const QString &dir1, const QString &dir2);
    static bool _dir_exists(const QString &dir, const QString &dir1, const QString &dir2, const QString &dir3);

    // :manifest
    static QString manifest(const QString &dir);
    static QString manifest_json_str(const QString &dir);
    static QJsonDocument manifest_json_document(const QString &dir);
    static QJsonObject manifest_json_object(const QString &dir);
    static Result manifest_branch(const QString &dir);

    // :info
    static QString info(const QString &dir, const QString &name);

    // default: {}
    static QString revision(const QString &dir);
    static QString default_remote(const QString &dir);
    static QString default_revision(const QString &dir);
    static QString default_sync_j(const QString &dir);

    // project: []
    static QVariantList project(const QString &dir);
    static QStringList project_names(const QString &dir);

    // remote: []
    static QVariantList remote(const QString &dir);

    // .repo/project-objects/<name>.git
    static bool repo_project_objects_name_exists(const QString &dir, const QString &name);
    static bool repo_project_objects_name_config_validated(const QString &dir, const QString &name);

    // .repo/projects/<path>.git
    static bool repo_projects_path_exists(const QString &dir, const QString &path);
    static bool repo_projects_path_3rlinks_validated(const QString &dir, const QString &name, const QString &path);

    // [solution]: repo info
    static Validate repo_info_validate(const QString &dir, const QString &name);
    static QString repo_info_validate_slove_revision_not_found_fetch_missing_revision(const QString &dir, const QString &name, const QString &path);
    static void repo_info_validate_slove_revision_not_found_delete_and_resynchronize(const QString &dir, const QString &name, const QString &path);

    // git objects/pack tmp_pack_ ...
    static bool repo_project_objects_name_objects_pack_exists_tmp_pack_file(const QString &dir, const QString &name);
    static void repo_project_objects_name_objects_pack_clean_tmp_pack_file(const QString &dir, const QString &name);


    // helper fucntions
    static QString query_path_is_checked(const QString &dir, const QString &path);
    static Validate query_path_git_workspace_is_ok(const QString &dir, const QString &path);
    static void git_workspace_init(const QString &dir, const QString &path);

private:
    static QString run(const QString &dir, const QString &cmd, const QStringList &args = QStringList(), bool merge_channel = false);
    static int run_exit_code(const QString &dir, const QString &cmd, const QStringList &args = QStringList());
};

#endif // REPOUTIL_H
